<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>模拟红绿灯</title>

  <style>
    html, body {
      width: 100%;
      height: 100%;
      padding: 0;
      margin: 0;
      overflow: hidden;

      /*设置html和body元素的布局为弹性布局*/
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    header {
      line-height: 2rem;
      font-size: 1.2rem;
      margin-bottom: 20px;
    }
    .traffic { /*将class=traffic元素设置为弹性布局，它的子元素按照从上面到下排列*/
      padding: 10px;
      display: flex;
      flex-direction: column;
    }
    .traffic .light {
      width: 100px;
      height: 100px;
      background-color: #999;
      border-radius: 50%;
    }

    /*将class=traffic & class=pass元素下的第一个class=light的元素的背景色设置为绿色*/
    .traffic.pass .light:nth-child(1) {
      background-color: #0a6; /*绿灯*/
    }
    .traffic.wait .light:nth-child(2) {
      background-color: #cc0; /*黄灯*/
    }
    .traffic.stop .light:nth-child(3) {
      background-color: #c00; /*红灯*/
    }
  </style>
</head>
<body>
  <header>模拟交通灯</header>
  <main>
    <div class="traffic pass">
      <div class="light"></div>
      <div class="light"></div>
      <div class="light"></div>
    </div>
  </main>

  <script>
    const traffic = document.querySelector('.traffic')

    // function signalLoop(subject, signals = []) {
    //   const signalCount = signals.length
    //   function updateState(i) {
    //     const {signal, duration} = signals[i % signalCount]
    //     subject.className = signal
    //     setTimeout(updateState.bind(null, i + 1), duration)
    //   }

    // }

    // function wait(ms) {
    //   return new Promise(resolve => {
    //     setTimeout(resolve, ms)
    //   })
    // }

    // (
    //   async function () {
    //     while(1) {
    //       await wait(5000)
    //       traffic.className = 'traffic wait'
    //       await wait(1500)
    //       traffic.className = 'traffic stop'
    //       await wait(3500)
    //       traffic.className = 'traffic pass'
    //     }
    //   }()
    // )

    function wait(ms) {
      return new Promise(resolve => {
        setTimeout(resolve, ms)
      })
    }

    async function signalLoop(subject, signal = [], onSignal) {
      const signalCount = signal.length
      for (let i = 0; ; i++) {
        const {signal, duration} = signal[i % signalCount]
        await onSignal(subject, signal)
        await wait(duration)
      }
    }

    const signals = [
      {signal: 'pass', duration: 5000},
      {signal: 'wait', duration: 3500},
      {signal: 'stop', duration: 1500},
    ];

    signalLoop(traffic, signals, (subject, signal) => {
      subject.className = `traffic ${signal}`;
    });


  </script>
</body>
</html>